(function() {
    var crashElment = function() {

    }
var revolver = function() {
    var context = this;
    this.activate = function() {
        initImages(function(){
            context.getSettings ();
            createDOM();
            attachEvents();
            cartridgesCount = 6;
        });
    };
    this.splinners = []
    var animationIntervalId = null;
    var volume = 0.8;
    var show_target = true;
    var frame = null;
    var placeholder = null;
    var _targetElement = null;
    var __domCanvas = null;
    var canvas = null;
    var cartridgesCount = 6;
    this.crashFrames = [];
    var imgs={};
    var angle = 0;
    var _angle = 0;
    var left = 0;
    var _left = 0;
    var top = 0;
    var images = [
        {id:"shoot", url: chrome.extension.getURL("img/revolver/shoot.png")}
        , {id:"reload", url: chrome.extension.getURL("img/revolver/reload.png")}
        , {id:"bullet", url: chrome.extension.getURL("img/bullet.png")}
    ];
    var sounds = {
        "shoot": chrome.extension.getURL("sound/gun15.wav")
        , "reload": chrome.extension.getURL("sound/reload6.wav")
        , "activate": chrome.extension.getURL("sound/reload3.wav")
    }

    var actions = {
        "no_actions": [
            {img: imgs.shoot, x: 0, y: 0, w: 270, h: 270}
        ]
        , "shoot": [
            {x: 0, y: 0, w: 270, h: 270}
            , {x:280, y:0, w: 270, h: 270}
            , {x: 560, y: 0, w: 270, h: 270 }
            , {x: 840, y: 0, w: 270, h: 270 }
            , null
        ]
        , "reload": [
            { x:0, y:0, w: 270, h: 250 }
            , { x:280, y:0, w: 270, h: 270}
            , { x:560, y:0, w: 270, h: 270 }
            , {x: 840, y: 0, w: 270, h: 270 }
            , {x: 1120, y: 0, w: 270, h: 270 }
            , {x: 1400, y: 0, w: 270, h: 270 }
            , {x: 1680, y: 0, w: 270, h: 270 }
            , {x: 1960, y: 0, w: 270, h: 270 }
            , {x: 0, y: 280, w: 270, h: 270 }
            , {x: 280, y: 280, w: 270, h: 270 }
            , {x: 560, y: 280, w: 270, h: 270 }
            , {x: 840, y: 280, w: 270, h: 270 }
            , {x: 1120, y: 280, w: 270, h: 270 }
            , null
        ]
    };
    var animationFrameCount = 0;

    this.getSettings = function() {
        askSetting("volume", function(val){
            volume = val || 0.8;
        });
        askSetting("show_target", function(val){
            show_target = val!=null ? val == "true" : false;
            if(!show_target) hideTarget();
        });
    };

    function initImages(callback) {
        var _initCount = 0;
        for(var i=0; i<images.length; i++) {
            _initCount++;
            var img = document.createElement("img");
            img.id = images[i].id;
            img.onload = function(e) {
                _initCount--;
                imgs[e.target.id] = e.target;
                if(_initCount==0 && i==images.length) {
                   callback();
                }
            }
            img.src=images[i].url;
        }
    };

    this.deactivate = function() {
        window.removeEventListener("mouseover", onMouseOver, false);
        window.removeEventListener("mouseout", onMouseOut, false);
        window.removeEventListener("mousemove", onMouseMove, false);
        clearInterval(animationIntervalId);
        removeElement(placeholder);
        document.body.className = document.body.className.replace(" _sia", "");
    };

    var attachEvents = function() {
        window.addEventListener("mouseover", onMouseOver, false);
        window.addEventListener("mouseout", onMouseOut, false);
        window.addEventListener("mousemove", onMouseMove, false);
        window.addEventListener("resize", onWindowResize, false);
    };

    var currentAction ="no_actions";

    var playSound = function(action) {
        var shoutSound = new Audio();
        shoutSound.src = sounds[action];
        shoutSound.volume = volume;
        shoutSound.play();
    };

    var onWindowResize = function() {
       if(__domCanvas) {
           __domCanvas.height = frame.clientHeight;
           __domCanvas.width = frame.clientWidth;
           top = __domCanvas.height-250;
       }
    }

    var onMouseOver = function(e) {
        e.stopPropagation();
        var _sender = e.target;

        switch(getTargetType(_sender)) {
            case "object":
                var _objTarget = createObjectTarget();
                setOver(_sender, _objTarget, true);
                _objTarget.relTarget = _sender;
                _objTarget.addEventListener("mousedown", function(e) {
                    kill(e.target);
                }, false);
                _objTarget.addEventListener("click", cancelEvent, false);
                _objTarget.addEventListener("mouseup", cancelEvent, false);
                break;
            case "object_target":
            case "dom":
                _sender.addEventListener("mousedown", onShout, false);
                _sender.addEventListener("click", cancelEvent, false);
                _sender.addEventListener("mouseup", cancelEvent, false);
                var _target = getTargetElement();
                if(_target) {
                    setOver(_sender, _target, false);
                }
                break;
            case "document":
                hideTarget();
                _sender.addEventListener("mousedown", onShout, false);
                _sender.addEventListener("click", cancelEvent, false);
                _sender.addEventListener("mouseup", cancelEvent, false);
            break;
            default: hideTarget();
        }
        return false;
    };

    var createObjectTarget = function() {
        var _objTarget = document.createElement("div");
        _objTarget.className="sia_object_target";
        placeholder.appendChild(_objTarget);
        return _objTarget;
    }

    var setOver = function(el1, el2, absolute) {
        var rect = el1.getBoundingClientRect();
        if(absolute) {
            var body = document.body
            var docElem = document.documentElement
            var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
            var clientTop = docElem.clientTop || body.clientTop || 0;
            var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
            var clientLeft = docElem.clientLeft || body.clientLeft || 0;
            el2.style.top = rect.top +  scrollTop - clientTop-3+"px";
            el2.style.left = rect.left + scrollLeft - clientLeft-3+"px";
        }
        else {
            el2.style.top = rect.top -3+"px";
            el2.style.left = rect.left -3+"px";
        }
        el2.style.height = rect.height + "px";
        el2.style.width = rect.width+"px";
    };

    var onMouseOut = function(e) {
        e.stopPropagation();
        var _sender = e.target;
        switch(getTargetType(_sender)) {
            case "object_target":
                    removeElement(_sender);
                break;
            case "dom":
                _sender.removeEventListener("mousedown", onShout, false);
                _sender.removeEventListener("click", cancelEvent, false);
                _sender.removeEventListener("mouseup", cancelEvent, false);
                break;
            case "document":
                _sender.removeEventListener("mousedown", onShout, false);
                _sender.removeEventListener("click", cancelEvent, false);
                _sender.removeEventListener("mouseup", cancelEvent, false);
                break;
        }
    };

    var cancelEvent = function(e) {
        e.stopPropagation();
        e.preventDefault();
        return false;
    };


    var onMouseMove = function(e) {
        var x = e.clientX;
        var y = e.clientY;
        var w = frame.clientWidth;
        var h = frame.clientHeight;

        var d = (h-y) * -1.1 + 550;
        d = d > 300 ? 300 : d;
        d = d < -350 ? -350 : d;
        left = x + d;

        angle = (h-y)*0.002 - 0.75;
        angle = angle > 0.796 ? 0.796 : angle;
        angle = angle < -0.722 ? -0.722 : angle;
    };

    var onShout = function(e) {
        e.stopPropagation();
        e.preventDefault();
        var _sender = e.target;
        kill(_sender, e.clientX, e.clientY);
        return false;
    };

    var kill = function(el, x, y) {

        if(currentAction=="reload") return;
        setAction("shoot");
        el.onclick = null;
        el.href = null;
        cartridgesCount--;
        setTimeout(function(){
            playSound("shoot");
            switch(getTargetType(el)) {
                case "dom":
                    crashElement(el, x, y);
                    removeElement(el);
                    hideTarget();
                    break;
                case "object_target":
                    crashElement(el, x, y);
                    removeElement(el.relTarget);
                    removeElement(el);
                    break;
                case "document": {
                    var bullet =  document.createElement("img");
                    bullet.src = chrome.extension.getURL("img/bullet.png");
                    bullet.className="sia_bullet";
                    bullet.style.top = y - 14 +"px";
                    bullet.style.left = x - 14 +"px";
                    document.body.appendChild(bullet);
                }
            }
            if(cartridgesCount<=0) {
                reload();
            }
        },200);
    }

    var reload = function() {
        setAction("reload");
        playSound("reload");
    }

    var removeElement = function(el) {
        if(el) {
            el.parentNode.removeChild(el);
        }
    };


    var hideTarget = function() {
        if(_targetElement)
            _targetElement.style.display="none";
    };

    var getTargetType = function(sender) {
        if(sender.tagName.toLowerCase()== "object" || sender.tagName.toLowerCase()=="iframe" || sender.tagName.toLowerCase()=="embed") {
            return "object";
        }
        if(sender.className=="sia_object_target") {
            return "object_target";
        }
        if(sender.tagName.toLowerCase()!= "body" && sender.tagName.toLowerCase() != "html") {
            return "dom";
        }
        if(sender.tagName.toLowerCase()== "body" || sender.tagName.toLowerCase() == "html") {
            return "document";
        }
    };

    var createDOM = function() {
        placeholder = document.createElement("div");
        placeholder.className="sia_placeholder";
        document.body.appendChild(placeholder);
        frame = document.createElement("div");
        frame.className="sia_frame";
        placeholder.appendChild(frame);
        var background = document.createElement("div");
        background.className="sia_background";
        frame.appendChild(background);
        document.body.className +=" _sia";
        __domCanvas = document.createElement('canvas');
        __domCanvas.className = "sia_canvas";

        context.ctx = canvas = __domCanvas.getContext("2d");
        frame.appendChild(__domCanvas);
        onWindowResize();
        runAnimation();
    };


    var setAction = function(action) {
        if(action=="reload") {
            frame.className="sia_frame sia_frame_reload";
        }
        else {
            frame.className="sia_frame";
        }
        currentAction = action;
        animationFrameCount = 0;
    };

    var getLeft = function() {
        if(!_left) {
             _left = left;
        }
        else {
            if(_left != left) {
               var _delta = left - _left;
                _left += _delta/3;
            }
        }
        return _left;
    }

    var getAngle = function() {
        if(!_angle) {
            _angle = angle;
        }
        else {
            if(_angle != angle) {
                var _delta = angle - _angle;
                _angle += _delta/3;
            }
        }
        return _angle;
    }

    var frame_duration = 3;
    var getFrame = function() {
        if(actions[currentAction].length>animationFrameCount) {
            var _frame = actions[currentAction][animationFrameCount];
            frame_duration--;
            if(frame_duration==0) {
                animationFrameCount++;
                frame_duration = 3;
            }
            if(_frame) {
               return _frame;
            }
            else {
                if(currentAction=="reload") {
                    cartridgesCount = 6;
                }
                setAction("no_actions");
                return getFrame();
            }
        }
        else {
            animationFrameCount = 0;
            return getFrame();
        }
    };

    function getImage(action) {
        switch(action) {
            case "no_actions":
            case "shoot":
                return imgs.shoot;
            case "reload":
                return imgs.reload;
            break;
        }
    };

    var runAnimation = function() {

        animationIntervalId = setInterval(function(){
            canvas.clearRect(0, 0, __domCanvas.width, __domCanvas.height);
            var _frame = getFrame();

            var img = getImage(currentAction);

            if(context.splinners.length>0) {
                for(var i= 0; i<context.splinners.length; i++) {
                    context.splinners[i].draw(canvas);
                }
            }


            canvas.save();
            canvas.translate(left+200, top+500);
            if(currentAction!= "reload")
                canvas.rotate(getAngle());
            canvas.translate(-200, -500);

            if(img) {
                canvas.drawImage(img, _frame.x, _frame.y, _frame.w, _frame.h, 0, 0, _frame.w, _frame.h);
            }
            canvas.restore();

        }, 1000/30);
    };

    var crashElement = function(el, x, y) {
        var rect = el.getBoundingClientRect();
        canvas.drawImage(imgs["bullet"],x-14,y-14);
        getScreensot(rect.left, rect.top, rect.width, rect.height, x, y);
    }

    var getTargetElement = function() {
        if(show_target) {
        if(!_targetElement) {
            _targetElement = document.createElement("div");
            _targetElement.className="sia_target";
            _targetElement.style.backgroundImage="url("+chrome.extension.getURL("img/target2.png")+")";
            frame.appendChild(_targetElement);
        }
        _targetElement.style.display = "block";
        return _targetElement;
        }
    }
};
    var revolv = null;


    Number.prototype.degree = function () {
        return this * Math.PI / 180;
    };


    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            if (request.message == "activate") {
                if(!revolv) {
                    revolv = new revolver();
                    revolv.activate();
                }
                sendResponse({"message": "OK"});
            }
            else if(request.message == "deactivate") {
                if(revolv) {
                    revolv.deactivate();
                    revolv = null;
                }
                sendResponse({"message": "OK"});
            }
            else if(request.message=="settings") {
                if(revolv) {
                    revolv.getSettings();
                }
                sendResponse({"message": "OK"});
            }
            else if(request.message=="screenshot") {
                var _img = document.createElement('img');
                _img.onload = function() {
                    var crashFrame = CanvasUtils.getImageSector(_img, request.x, request.y,request.w,request.h);
                    revolv.splinners = Splinner.createSplinnersByPoint(crashFrame, request.x1-request.x, request.y1-request.y, request.x, request.y, revolv.ctx);
                    setTimeout(function(){revolv.splinners=[]}, 1000);
                }
                _img.src = request.image;
            }
        });
    function askSetting(setting, callcback) {
        chrome.runtime.sendMessage({action:"settings", setting: setting}, function(response) {
            callcback(response.value);
        });
    }
    function getScreensot(x,y,w,h, x1, y1) {
        chrome.runtime.sendMessage({action: "screenshot",x:x,y:y,w:w,h:h, x1:x1, y1:y1}, function(response) {

        });
    }
})();